using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace IconConverter
{
    class IconConverter
    {
        private static string ByteToHex(byte byteValue)
        {
            return byteValue.ToString("X2");
        }
        private static byte HexToByte(string byteString)
        {
            return byte.Parse(byteString, System.Globalization.NumberStyles.HexNumber);
        }
        static void IcoToHex(string filePath)
        {
            byte[] buffer = null;
            FileStream fileStream = null;
            BinaryReader reader = null;
            try
            {
                fileStream = File.Open(filePath, FileMode.Open);
                reader = new BinaryReader(fileStream);
                int byteLength = (int)reader.BaseStream.Length;
                buffer = new byte[byteLength];
                reader.Read(buffer, 0, byteLength);
            }
            catch
            {
                Console.WriteLine("Cannot read file \"{0}\".", filePath);
            }
            finally
            {
                if (fileStream != null)
                {
                    fileStream.Close();
                }
                if (reader != null)
                {
                    reader.Close();
                }
            }
            FileInfo fileInfo = new FileInfo(filePath);
            string outputPath = fileInfo.FullName.Replace(fileInfo.Extension, ".hex");
            StringBuilder builder = new StringBuilder(buffer.Length * 2);
            foreach (byte b in buffer)
            {
                builder.Append(ByteToHex(b));
            }
            StreamWriter writer = null;
            try
            {
                writer = new StreamWriter(outputPath);
                writer.Write(builder.ToString());
            }
            catch
            {
                Console.WriteLine("Cannot write file \"{0}\".", outputPath);
            }
            finally
            {
                if (writer != null)
                {
                    writer.Close();
                }
            }
        }
        static void HexToIco(string filePath)
        {
            string hexString = null;
            StreamReader reader = null;
            try
            {
                reader = new StreamReader(filePath);
                hexString = reader.ReadToEnd();
                if ( (hexString.Length % 2) != 0)
                {
                    Console.WriteLine("File {0} is invalid.");
                    return;
                }
            }
            catch
            {
                Console.WriteLine("Cannot read file \"{0}\".", filePath);
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                }
            }
            FileInfo fileInfo = new FileInfo(filePath);
            string outputPath = fileInfo.FullName.Replace(fileInfo.Extension, ".ico");
            byte[] buffer = new byte[hexString.Length / 2];
            for (int i = 0; i < buffer.Length; i++)
            {
                string byteString = hexString.Substring(i * 2, 2);
                buffer[i] = HexToByte(byteString);
            }
            FileStream fileStream = null;
            BinaryWriter writer = null;
            try
            {
                fileStream = File.Open(outputPath, FileMode.Create);
                writer = new BinaryWriter(fileStream);
                writer.Write(buffer);
            }
            catch
            {
                Console.WriteLine("Cannot write file \"{0}\".", outputPath);
            }
            finally
            {
                if (fileStream != null)
                {
                    fileStream.Close();
                }
                if (reader != null)
                {
                    reader.Close();
                }
            }
        }
        static void Main(string[] args)
        {
            if (args.Length > 0)
            {
                FileInfo fileInfo = new FileInfo(args[0]);
                string filePath = fileInfo.FullName;
                if (fileInfo.Exists)
                {
                    if (fileInfo.Extension.ToLower() == ".ico")
                    {
                        IcoToHex(filePath);
                    }
                    else
                    {
                        if (fileInfo.Extension.ToLower() == ".hex")
                        {
                            HexToIco(filePath);
                        }
                        else
                        {
                            Console.WriteLine("File extension not recognized.");
                        }
                    }
                }
                else
                {
                    Console.WriteLine("File {0} cannot be found.", args[0]);
                }
            }
            else
            {
                Console.WriteLine(
                    "Usage: IconConverter <iconfile>.ico | <iconfile>.hex");
            }
        }
    }
}
